﻿
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.UI;

[ToolButton("文本处理","导出文本")]
public class TextExport: IToolsButtonEvent
{
    const string prefabSuffix = ".prefab";
    const string assetSuffix = ".asset";
    const string savePath = "GameConfigure/Language.xlsx";
    const string saveComponentPath = "GameConfigure/TextComponent.xlsx";
    static Type stringType = typeof(string);
     //ExcelTable languageTable;
     ExcelTable componentTable;
     int componentRow;
    HashSet<string> hash = new HashSet<string>();
    public void Run()
    {
       
        try
        {
            hash.Clear();
            var path = Directory.GetFiles(Application.dataPath, "Language.xlsx", SearchOption.AllDirectories)
           .Where(s => s.IndexOf(@"EditorTools\Editor\Realize\String Processing\Language.xlsx") != -1).FirstOrDefault();
            
            var componentPath = Directory.GetFiles(Application.dataPath, "TextComponent.xlsx", SearchOption.AllDirectories)
            .Where(s => s.IndexOf(@"EditorTools\Editor\Realize\String Processing\TextComponent.xlsx") != -1).FirstOrDefault();

            var excel = ExcelHelper.LoadExcel(path);
            var languageTable = excel.Tables[0];

            var componentExcel = ExcelHelper.LoadExcel(componentPath);
            componentTable = componentExcel.Tables[0];
            componentRow = componentTable.NumberOfRows + 1;

            ExprotAsset();
            ExportPrefab();

#if UNITY_5_3
            foreach (var scene in EditorBuildSettings.scenes)
            {
                var name = Path.GetFileNameWithoutExtension(scene.path);
                EditorSceneManager.OpenScene(name);
                ExprotHierarchy();
            }
#else
              var array = EditorBuildSettingsScene.GetActiveSceneList(EditorBuildSettings.scenes);
            foreach (var scene in array)
            {
                EditorSceneManager.OpenScene(scene);
                ExprotHierarchy();
            }
#endif
            

            var languagerow = languageTable.NumberOfRows + 1;
            foreach(var item in hash)
            {
                languageTable.SetValue(languagerow, 1, item);
                languagerow++;
            }
            if(!Directory.Exists("GameConfigure"))
            {
                Directory.CreateDirectory("GameConfigure");
            }
            EditorUtility.ClearProgressBar();
            ExcelHelper.SaveExcel(excel, savePath);
            ExcelHelper.SaveExcel(componentExcel, saveComponentPath);
            Debug.Log("输出完成");
            System.Diagnostics.Process.Start(savePath.Replace('/','\\'));
            System.Diagnostics.Process.Start(saveComponentPath.Replace('/', '\\'));
        }
        catch (Exception ex)
        {
            Debug.LogError(ex);
        }
    }

    void ExportPrefab()
    {
        //var array = Resources.FindObjectsOfTypeAll<GameObject>(); //该函数有时无法获得Prefab
        var files = Directory.GetFiles(Application.dataPath, "*.*", SearchOption.AllDirectories)
        .Where(s => prefabSuffix.Contains(Path.GetExtension(s).ToLower())).ToArray();

        List<UnityEngine.Object> list = new List<UnityEngine.Object>();
        foreach (var file in files)
        {
            var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(file.Substring(file.IndexOf("Assets")));
            list.Add(prefab);
        }

        Selection.objects = list.ToArray();
        var array = Resources.FindObjectsOfTypeAll<GameObject>();
        int index = 0;
        foreach (var item in array)
        {
            EditorUtility.DisplayProgressBar("导出prefab", item.name, (float)index / array.Length);
            var path = AssetDatabase.GetAssetPath(item);
            if (string.IsNullOrEmpty(path))
                continue;
            if (path.IndexOf(@"EditorTools/Res/") != -1|| path.IndexOf(@"EditorTools/Resources/") != -1)
            {
                continue;
            }
            SearchString(item);
        }
        Selection.objects = new UnityEngine.Object[] { };
    }

    void ExprotAsset()
    {
        var files = Directory.GetFiles(Application.dataPath, "*.*", SearchOption.AllDirectories)
         .Where(s => assetSuffix.Contains(Path.GetExtension(s).ToLower())).ToArray();

        int index = 0;
        foreach (var file in files)
        {
            var obj = AssetDatabase.LoadMainAssetAtPath(file.Substring(file.IndexOf("Assets")));
            EditorUtility.DisplayProgressBar("导出Asset", file, (float)index++ / files.Length);
            try
            {
                var json = JsonUtility.ToJson(obj);
                JsonHelper.Foreach(json, obj.GetType(), (type, key, value) =>
                {
                    if (type == typeof(string) || type.IsSubclassOf(typeof(string)))
                    {
                        //table.SetValue(row, 1, value.ToString());
                        //table.SetValue(row, 9, file);
                        //componentRow++;
                       // Debug.LogError(value);
                        if (!hash.Contains(value.ToString()))
                        {
                            hash.Add(value.ToString());
                        }
                    }
                });
            }
            catch
            {

            }
        }
    }

    void ExprotHierarchy()
    {
        var array = Resources.FindObjectsOfTypeAll<GameObject>();
        int index = 0;
        foreach (var item in array)
        {
            EditorUtility.DisplayProgressBar("导出prefab", item.name, (float)index / array.Length);
            if (!string.IsNullOrEmpty(AssetDatabase.GetAssetPath(item)))
                continue;
            SearchString(item);
        }
    }

    void SearchString(GameObject go)
    {
        foreach (var com in go.GetComponents<MonoBehaviour>())
        {
            if (com == null || com is LanguageManager)
                continue;
            JsonHelper.Foreach(JsonUtility.ToJson(com), com.GetType(), (type, key, value) =>
             {
                 if (type == stringType || type.IsSubclassOf(stringType))
                 {
                     WriteExcel(go, com, value.ToString());
                 }
             });
        }
    }

    void WriteExcel(GameObject go, MonoBehaviour behaviour, string value)
    {
        if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(value.Trim()))
            return;

        var path = AssetDatabase.GetAssetPath(go);
        if (string.IsNullOrEmpty(path))
            path = EditorSceneManager.GetActiveScene().path;

        //table.SetValue(row, 1, value);
        //if (behaviour is Text)
        //{
        //    var text = behaviour as Text;
        //    table.SetValue(row, 3, text.font.name);
        //    table.SetValue(row, 4, text.fontSize.ToString());
        //    table.SetValue(row, 5, text.color.ColorToHex());
        //}
        //table.SetValue(row, 9, path);
        //table.SetValue(row, 10, go.GetPath());
        //Debug.LogError(go);
        if (!hash.Contains(value))
        {
            hash.Add(value);
        }

        bool isWrite = behaviour is Text || behaviour.GetType().IsSubclassOf(typeof(Text));

        if (!isWrite)
            return;

        componentTable.SetValue(componentRow, 1, path);
        componentTable.SetValue(componentRow, 2, go.GetPath());
        var text = behaviour as Text;
        if (text.font != null)
        {
            componentTable.SetValue(componentRow, 3, text.font.name);
        }
        componentTable.SetValue(componentRow, 4, text.fontSize.ToString());
        componentTable.SetValue(componentRow, 5, text.color.ColorToHex());
        var outline = text.GetComponent<Outline>();
        if (outline != null)
        {
            componentTable.SetValue(componentRow, 6, outline.effectDistance.x.ToString());
            componentTable.SetValue(componentRow, 7, outline.effectColor.ColorToHex());
        }
        componentRow++;
    }
}
